﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using ITAP.ContourBuilder.Components;

using ITAP.ContourBuilder.Components.Dimensions;
using ITAP.Core.Modelling;

namespace ITAP.ContourBuilder.Manipulation
{
    public class CommandAddComponentLeaderDimension : SerializedCommand
    {
        private List<Type> selectPriority;
        IEnumerable<IContourComponent> allComponents;

        public CommandAddComponentLeaderDimension(ContourControl control)
            : base(control)
        {
            selectPriority = new List<Type>();

            selectPriority.Add(typeof(ContourConnector));
            selectPriority.Add(typeof(ContourHole));
            
            allComponents = this.control.ContourContainer.GetAllInnerComponents();               
        }

        private Point preMousePoint;
        private IContourComponent component1 = null;
        private IContourComponent component2 = null;
        private ComponentLeaderDimension dimension;
        private bool mouseMoved = false;

        public override void ObtainPeripheryState(GlobalPeripheryState state)
        {
            base.ObtainPeripheryState(state);

            if (state.KeyboardState.KeyMode == KeyMode.Down && state.KeyboardState.KeyState.KeyCode == Keys.Escape)
            {
                this.Cancel();
                return;
            }

            if (state.MouseState.MouseMode == MouseMode.Down && state.MouseState.State.Button == MouseButtons.Left)
            {
                ModelPoint point = this.ScreenPointToModelPoint(state.MouseState.State.Location);
                foreach (Type type in selectPriority)
                {
                    foreach (IContourComponent component in allComponents)
                    {
                        if (component.GetType() != type)
                            continue;

                        if(component1 == null)
                            if (component.CanSelectByPoint(point))
                            {
                                component1 = component;
                                return;
                                //continue;
                            }   

                        if(component2 == null)
                            if (component != component1 && component.CanSelectByPoint(point))
                            {
                                component2 = component;

                                dimension = (ComponentLeaderDimension)DimensionFactory.CreateComponentLeaderDimension(component1, component2, GlobalData.DimensionTextFont, "");
                                component1.GetRootModel().AddInnerComponent(dimension);
                                preMousePoint = state.MouseState.State.Location;
                                return;
                            }
                    }
                }               
            }
            else if (state.MouseState.MouseMode == MouseMode.Move && state.MouseState.State.Button == MouseButtons.Left)
            {
                if (dimension == null)
                {
                    this.Cancel();
                    return;
                }
                ModelPoint prevPoint = this.ScreenPointToModelPoint(preMousePoint);
                ModelPoint point = this.ScreenPointToModelPoint(state.MouseState.State.Location);
                ModelVector vector = new ModelVector(prevPoint, point);

                if (!mouseMoved && vector.Length < 10)
                    return;

                if (!mouseMoved)
                {
                    mouseMoved = true;
                    if (Math.Abs(vector.X) > Math.Abs(vector.Y))
                    {
                        dimension.LeaderType = LeaderDimensionType.Horizontal;
                        dimension.PrefixSymbol = "Y";
                    }
                    else
                    {
                        dimension.LeaderType = LeaderDimensionType.Vertical;
                        dimension.PrefixSymbol = "X";
                    }
                }
                if(dimension.LeaderType == LeaderDimensionType.Vertical)
                    dimension.OffsetFromPrimitive += vector.Y; 
                else
                    dimension.OffsetFromPrimitive += vector.X; 
                

                preMousePoint = state.MouseState.State.Location;
                dimension.Recalculate();
                this.control.Invalidate();
            }
            else if (state.MouseState.MouseMode == MouseMode.Up && state.MouseState.State.Button == MouseButtons.Left)
            {
                if(component1 != null && component2 != null)
                    this.Exit();
            }
        }

        public override string ToString()
        {
            return "Создать размер от двух элементов";
        }
    }
}
